//	--------------------------------------------------------------------
//	Copyright(C) 2006,2007 Zhao Yukun. All rights reserved.
//	This file is a part of the Xeres system.
//	Xeres 2007
//	Contact : xeres.engine@gmail.com
//	$(reservedInfo)
//	$(reservedDeclaration)
//	--------------------------------------------------------------------
///	@file	<xeres_engine.h>
///	@path	~/src/engine/xcore/
///	@date	2007/09/23
///	@desc	Engine integration.

#pragma once

#include "xeres.h"

#include "lib/system/lock.h"
#include "lib/system/thread.h"
#include "lib/system/signal.h"
#include "lib/utilities/time.h"
#include "lib/utilities/dep_stages.h"
#include "lib/utilities/callback.h"

#include "database/DataManager.h"

#include "graphics/IDevice.h"
#include "graphics/IRenderer.h"
#include "graphics/RenderManager.h"


#include "engine/engine.h"
#include "engine/xcore/initors.h"
#include "engine/xcore/resource_center.h"
#include "engine/xcore/timer_center.h"
#include "engine/xcore/event_center.h"
#include "engine/xcore/loop_scheduler.h"
#include "engine/xcore/task_manager.h"
#include "engine/xcore/logic_manager.h"

#include "engine/xcore/engine_debug.h"

#include <deque>

namespace xeres {

	// forward declaration
	class EventCenter;

	class IEffect;
	class IGeometry;

	/*!
		\class	Engine
		\brief	Engine integration. Nearly everything goes here.
				User use this class to :
					configurate engine,
					schedule process,
					queue game logic,
					manage data.
	*/
	class ALIGNED Engine
		// Framework Components
		: public LoopScheduler , public TimerCenter , public EventCenter , public ResourceCenter
		// Game Logic Components
		, public LogicManager
		// Helpers Components
		, public Initors
		// Debug Components
		, public EngineDebug
	{
	public:

		/// \instance
		static Engine& instance( void );

		/// From Frame to Engine
		static Engine& fromFrame( const Frame& frame );

		/// \name Engine Configuration
		//@{

		/*!
			\brief		Config device for engine.
		*/
		void ConfigDevice( void * main_window , const WString& device , const WString& renderer ,
			RefWeak<IData> device_config , RefWeak<IData> renderer_config );

		/*!
			\brief		Creates dispatching job pool.
		*/
		void ConfigMultiTasking( RefWeak<IData> pool_config );

		/*!
			\brief		Config scene settings.
		*/
		void ConfigScene( RefWeak<IData> scene_config );

		//@}

		/// \name Engine Events
		//@{

		

		//@}


	// startup & cleanup

		/*!
			\brief		Initialize engine & components.
						Notice this function only initialize some
						pre-defined components and environments,
						it doesn't initialize queued initializer for
						customized components, they will be executed
						when the first time 'tick' runs.
		*/
		void Initialize( void );

		/*!
			\brief		The first frame update call.
						Performs all queued initialization.
		*/
		void FirstFrame( void );

		/*!
			\brief		Do all last cleanup works which must perform during update.
						The last frame update call, usually does not cleanup
						environments and global variables.
		*/
		void LastFrame( void );

		/*!
			\brief		Finalize engine & components.
						Cleanup environments and global variables.
		*/
		void Finalize( void );

		/*!
			\brief		Perform next frame update.
		*/
		void UpdateFrame( void );

	// resource

		// resource loading

		/*!
			\brief		Cache an HLSL effect from path.
		*/
		void CacheEffect( const WString& path );

		// resource creation

		/*!
			\brief		Queues an synchronized resource creation.
		*/
		void QueueSyncResourceCreator( function<void(RenderManager&)> res_call );

		//  render manipulator

	// rendering

	// scene

		/*!
			\brief		Schedule scene manager to preload specific scene which defined in scene config.
		*/
		void PreLoadScene( const WString& name , function<void(TaskResult)> complete_call );

		/*!
			\brief		Load a scene immediately without schedule it to background thread.
		*/
		bool InstantScene( const WString& name );

	// geometry


	private:

		/// \ctor
		Engine( void );

		/// \dtor
		~Engine( void );

		// sub callbacks

		/// \brief		Initialize Renderer
		void InitializeRenderer( void );

		/// \brief		Present scene callback
		void Present( void );

		/// \brief		Cull presentation
		void Cull( void );

		/*!
			\brief		Update synchronized resource callback.
		*/
		void UpdateSyncResourceCall( void );

	//@ data

		// state tags
		bool				m_inited;
		bool				m_firstFrame;
		bool				m_updating;
		bool				m_spare0;

		// sub stage callbacks
		std::deque< function<void(RenderManager&)> > m_loopSyncResourceCalls;

	};

} // namespace xeres
